#include "../src/pciHeader.c"
#include "../include/video.h"


/* Funcion que devuelve un registro del PCI Device Structure de
 * un determinado dispositivo PCI. Para seleccionar el dispositivo,
 * la funcion debe recibir el bus correspondiente, el device y la
 * funcion, asi como tambien el registro que se solicita. */

unsigned int
selecDsp(unsigned int bus, unsigned int device, unsigned int function, unsigned int reg)
{
	unsigned int respuesta = 0;
	unsigned int auxiliar = 0;
	
	auxiliar = (unsigned int) 0x80000000 | (bus << 16) | (device << 11) | (function << 8) | reg;

	respuesta = _scanpci ( auxiliar );
	
	return respuesta;
}


/* Funcion que recibe el primer registro de la PCI Device
 * Structure, es decir 00, que corresponde al device ID y
 * vendor ID. La misma machea estos datos con la base de
 * datos de PCI e imprime en pantalla dichos datos. */

void
findDsp(unsigned int descriptor)
{
	unsigned int vendor = descriptor;
	unsigned int device = descriptor;

//	int i;

//	char * venName = 0;
//	char * devName = 0;

	vendor = vendor & 0x0000FFFF;
	device = device & 0xFFFF0000;
	device = device >> 16;

	prnHexa(vendor);
	prnChar(' ');
	prnHexa(device);
}

/* Al igual que la funcion anterior, esta funcion tambien
 * recibe un registro de la PCI Device Structure. En este caso
 * se trata del tercero, es decir 08, que contiene en los
 * 16 bits mas significativos la clase y subclase del dispositivo.
 * Los mismos se machean con la base de datos y se imprime en la
 * pantalla. */

void
classDsp (unsigned int descriptor)
{
	unsigned int classCode = 0;
	unsigned int subClass = 0;
	int i;	
	char *clase = "0";
	char *subclase = "0";

	descriptor = descriptor >> 16;
	subClass = descriptor & 0x000000FF;
	classCode = descriptor & 0x0000FF00;
	classCode = classCode >> 8;
	
	for (i=0; i< PCI_CLASSCODETABLE_LEN; i++)
	{
		if ( PciClassCodeTable[i].BaseClass == classCode )
		{
			clase = PciClassCodeTable[i].BaseDesc;
			subclase = "Subclase Desconocida";
			
			while ( PciClassCodeTable[i].SubClass <= subClass )
			{
				if ( PciClassCodeTable[i].SubClass == subClass )
				{
					subclase = PciClassCodeTable[i].SubDesc;
					break;
				}
				i++;
			}
			break;
		}
		else if ( PciClassCodeTable[i].BaseClass > classCode )
		{
			subclase = "Subclase Desconocida";
			clase  = "Dispositivo no encontrado";
			break;
		}
	}

	prnString(clase);
	prnChar(' ');
	prnString(subclase);
}

/* Funcion que recorre los 256 buses del pci, los 32 dispositivos
 * que corresponden a cada uno de los buses y las 8 funciones de
 * cada uno de los dispositivos. Si detecta un dispositivo (ya que
 * muchas posiciones van a estar libres), busca el nombre del
 * fabricante y del dispositivo asi como tambien la clase a la que
 * pertenecen. */

void
listPci(void)
{
	int i, j, k;
	unsigned int aux=0;
	/* En el primer ciclo se recorren los 256 buses del pci. */

	for (i=0; i<255; i++)
	{
		/* En el segundo ciclo se recorren los 32 dispositivos */

		for(j=0; j<31; j++)
		{
			/* En el tercer ciclo se rerorren las 7 funciones
			 * de cada dispositivo. */

			for(k=0; k<7; k++)
			{	
				/* Se analiza si en campo 0 del descriptor
				 * hay informacion de un dispositivo. */

				aux = selecDsp ( i, j, k, 0);
				if ( aux != 0xFFFFFFFF)
				{
					//prnHexa(aux);
					//prnChar(' ');
					aux = selecDsp ( i, j, k, 0x08);
					classDsp(aux);
					if ( (aux&0xFFFF0000) == 0x0C030000 )
					{
												
						aux = selecDsp ( i, j, k, 0x20);	
						//ioAddres = _scan ( aux );
						//aux = _usbacces(ioAddres, 0x8006001000001200);
						prnHexa (aux);

					}
					prnEnter();
				}
			}
		}
	}
	
}
